#include "stdafx.h"
  Mod_out_handling::Mod_out_handling(Mod_in *iinp)
  {
	inp=iinp;
  }
  Mod_out_handling::~Mod_out_handling(){;}
double Mod_out_handling::get_fluxes(string key,time_intervall &ti)
{
    if (out->fluxes.get_size()>0)
     {
         if(out->fluxes.get_last_time_intervall()>=ti)
         {
             return out->fluxes.get_rate (key,ti);
         }
     }
     compute_loop(ti);
     return out->fluxes.get_rate(key,ti);
}
double Mod_out_handling::get_fluxes(string identifier,int horizon ,time_intervall &ti)
{
    if ((out->field_of_fluxes.find(identifier))==out->field_of_fluxes.end())
    {
        err::err3("Mod_IO::get_fluxes: Such a variable does not exist in output :"+ identifier);
    }
    if (out->field_of_fluxes[identifier].check_for_keys(horizon))
    {
        err::err3("Mod_IO::get_fluxes: Such a horizon was not found for this variable:"+ identifier);
    }
    if ( out->field_of_fluxes[identifier].get_size()>0)
    {
        if(out->field_of_fluxes[identifier].get_last_time_intervall()>=ti)
        {
            return out->field_of_fluxes[identifier].get_rate(horizon,ti);
        }
    }
    compute_loop (ti);
    return out->field_of_fluxes[identifier].get_rate(horizon,ti);
}
int Mod_out_handling::set_push_back_fluxes(string key,time_intervall &ti, double wert)
{
     out->fluxes.set_push_back_val(key,ti, wert);
}
int Mod_out_handling::set_push_back_fluxes(string identifier,int key, time_intervall &ti, double wert)
{
    out->field_of_fluxes[identifier].set_push_back_val(key,ti,wert);
}
double Mod_out_handling::get_states (string key,timestamp &ts)
{
 if (out->states.find(key)==out->states.end())
     {
         err::err3("mod_ETP::get_states:No such key in states");
     }
 if (out->states[key].get_end()>=ts){
       return out->states[key].get_val_lin(ts);
 }
 compute_loop (ts);
 return out->states[key].get_val_lin(ts);
}
double Mod_out_handling::get_states ( string identifier, int key,timestamp &ts)
{
    if (out->field_of_states.find(identifier)== out->field_of_states.end())
    {
        err::err3("Mod_IO::get_states: No such variable exists:" +identifier);
    }
    if (out->field_of_states[identifier].find(key)==out->field_of_states[identifier].end())
    {
        err::err3("Mod_IO::get_states: No such horizon exists:");
    }
    if (out->field_of_states[identifier][key].get_end()>=ts){
        return out->field_of_states[identifier][key].get_val_lin(ts);
 }
 compute_loop (ts);
 return out->field_of_states[identifier][key].get_val_lin(ts);
}
int Mod_out_handling::set_states(string key,timestamp &ts,double wert)
{
    
    out->states.at(key).set_insert_or_replace_entry(ts,wert);
}
int Mod_out_handling::set_states(string identifier,int key,timestamp &ts,double wert)
{
    
    out->field_of_states.at(identifier).at(key).set_insert_or_replace_entry(ts,wert);
}


 int Mod_out_handling::compute_loop(time_intervall &ti)
 {
	//Berechnet ETP_ergebnisse und speichert es in out
	map <string,double> zwi;
        int row, maxrow;
        //1. check
        if(ti<=out->fluxes.get_last_time_intervall())
        {
            err::err3("mod_ETP::compute_loop: the values for the timeintervall do already exist, therefore no need for computation");
        }
        //1. finden der position für die erste Berechnung
        if (out->fluxes.get_size()==0)
        {
            row=0;
        }
        else
        {
            row=inp->tempgrid->get_pos_of_first_overlapping_intervall(out->fluxes.get_last_time_intervall());
        }
        if( (maxrow=inp->tempgrid->get_pos_of_last_overlapping_intervall(ti))==inp->tempgrid->get_size())
        {
            err::err3("mode_ETP::compute_loop: could not find the right timeintervall in tempgrid");
        }
        while (row<=maxrow)
	{
            time_intervall ti=inp->tempgrid->get_time_intervall(row);
            this->compute(ti);
		row++;
	}
	
	return 0;
 }
  int Mod_out_handling::compute_loop(timestamp &ts)
 {
	//Berechnet ETP_ergebnisse und speichert es in out
	map <string,double> zwi;
        int row, maxrow;
        //1. check
        if(ts<=out->fluxes.get_last_time_intervall().get_end())
        {
            err::err3("mod_ETP::compute_loop: the values for the timeintervall do already exist, therefore no need for computation");
        }
        //1. finden der position für die erste Berechnung
        if (out->fluxes.get_size()==0)
        {
            row=0;
        }
        else
        {
            row=inp->tempgrid->get_pos_where_ts_bigger_equal_than_this_start_but_not_end(ts);
                    
        }
        if( (maxrow=inp->tempgrid->get_pos_where_ts_smaller_equal_than_this_end_but_not_this_start (ts))==inp->tempgrid->get_size())
        {
            err::err3("mode_ETP::compute_loop: could not find the right timeintervall in tempgrid");
        }
        while (row<=maxrow)
	{
            time_intervall ti=inp->tempgrid->get_time_intervall(row);
            this->compute(ti);
		row++;
	}
	
	return 0;
 }
//Mod_out::Mod_out(tempmap *tempgrid)
//{
//   this->fluxes.set_basics(tempgrid);
//   map < string, timepointmap < double > >::const_iterator states_it;
//   for (states_it=states.begin();states_it!=states.end();states_it++)
//   {
//		states_it->second.set_basics(tempgrid);
//   }
//    map <string,tempmap <int,double> >::const_iterator field_of_fluxes_it;
//   for (states_it=states.begin();states_it!=states.end();states_it++)
//   {
//		states_it->second.set_basics(tempgrid);
//   } 
//   
//    
//}
//Mod_out::~Mod_out()
//{
//  
//}
int Mod_out_handling::define_field_of_states(string identifier,int nkey)
{
    int x;
    
    map < int, timepointmap < double > > dummy_states;
    timepointmap <double> null_timepointmap(this->inp->tempgrid);
    
    for (x=0;x<=nkey;x++)
    {
        dummy_states[x]=null_timepointmap;
    }
    out->field_of_states[identifier]=dummy_states;
    return 0; 
}

int Mod_out_handling::define_field_of_fluxes(string identifier,int nkey)
{
    tempmap  <int,double> dummy_fluxes(this->inp->tempgrid->get_nulldata(),
                                this->inp->tempgrid->get_nodata(),
                                this->inp->tempgrid->get_intervallmode(),
                                this->inp->tempgrid->get_multipli(),
                                this->inp->tempgrid->get_dur()) ; 
    
    int x;
     
    for (x=0;x<=nkey;x++)
    {
        dummy_fluxes.set_key(x);
    }
    this->out->field_of_fluxes[identifier]=dummy_fluxes;
    return 0;
    
}
double Mod_out_handling::get_dx(int	layer)
{
	if (layer==0) return inp->horizons->at(layer);
	else return inp->horizons->at(layer)-inp->horizons->at(layer-1);
}